Cognito認証による任意ユーザのLexボットアクセス
渡辺です。
LexボットはAWS上のサービスとして構築されます。 すなわち、Lexボットにアクセスするには AWSリソースへのアクセス が必要です。 原則として、AWSリソースへアクセスするには 認証情報 が必要であり、何らかの方法でクライアントが認証しなければなりません。
最も簡単にクライアントから認証する方法は、IAMユーザのアクセスキーとシークレットキーを使う方法です。 勿論、LambdaやEC2上での利用ならばIAMロールの利用がベストです。 しかし、iOS、Android、公開されたウェブページ上のJavaScriptなどに アクセスキーを晒すのは危険 です。
このようなケースでは、Cognitoを利用して認証しましょう。
Cognitoとは?
Amazon Cognito とは、ウェブアプリケーションやモバイルアプリケーションの認証、許可、ユーザー管理をサポートするサービスです。 例えば、FacebookやTwitterなどのログインと組み合わせ、認証済みのユーザにAWSリソースへのアクセス許可を与えます。 Cognitoの持つユーザプールを利用すれば、AWS単体で認証サービスを利用することも可能です。
今回、「任意のユーザがLexボットを利用する」という要件であるため、Cognitoの「認証されていないID」を利用します。 「認証されていないID」では、ログイン(認証)をせずに、Cognitoからアクセス許可を得られます。
フェデレーテッドユーザーアイデンティティの作成
はじめに、Cognitoでフェデレーテッドユーザーアイデンティティを作成します。 Cognitoの画面を開き、適当なIDプール名(LexBot)を付けてフェデレーテッドユーザーアイデンティティを作成してください。 この時、「認証されていないIDに対し、アクセスを有効にする」にチェックを入れておきます。
次の画面では、Cognitoで認証が行われた時に許可するアクセス許可を設定します。 アクセス許可はIAMロールとして設定しますが、IAMロール自体は自動的に作成されるため、ロール名をメモしておきましょう。 今回関連するアクセス許可は、認証をしていない場合のIAMロールなので、「Cognito_LexBotUnauth_Role」です。
フェデレーテッドユーザーアイデンティティが作成できたならば、サンプルコードからプラットフォームでJavaScriptを選択し、AWS認証情報の取得にあるコードをコピーしておきます。
アクセス許可の追加
認証していないユーザでCognitoにアクセスは出来るようになりました。 しかし、まだLexにアクセス出来ません。 アプリケーションなどで例えれば、ログインは可能でも、なにも操作権限がない状態です。 IAMの画面を開き、認証をしていない場合のIAMロール(Cognito_LexBotUnauth_Role)にアクセス許可を追加しましょう。
インラインポリシーの追加を選択し、サービスでLexを指定したならば、PutText
とPutContext
のアクションにチェックを入れます。
PutText
はLexに対し文字情報を送信するアクションで、PutContextは音声などバイナリを送信するアクションです。
テキストのみであれば、PutText
だけでも良いでしょう。
インラインポリシーには適当な名前をつけて保存します。
注意したいのは、特に、 認証なしで利用できるロールに対し、強力なアクセス許可を与えない ことです。 Administrator権限などは言語道断ですが、Lexのフルアクセス許可を与えてしまうと、Lexボットを削除したり、Lexボットの挙動を変えることも可能です。
クライアントからの利用
以上で認証不要でLexクライアントが利用できる準備ができました。 先ほどのサンプルコードを元に、JavaScriptでクライアントの実装を行うことができます。
要点のみを抽出したコードは次のようになるでしょう。
AWS.config.region = 'us-east-1'; AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: 'us-east-1:xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx', }); var lex = new AWS.LexRuntime(); var postMessage = function(message) { var params = { botName: 'LexBot', botAlias: 'Prod', userId: 'anonymous', inputText: message }; lex.postText(params, function(err, data) { if (err) { console.log(err, err.stack); return; } console.log(JSON.stringify(data)); }); };
まとめ
クライアントからLexボットにアクセスするには、AWSリソースへのアクセス許可が必要です。 アクセス許可を得るには、Cognitoを利用します。 Cognitoでは認証なしで利用できるオプションがあるため、認証なしでアクセス許可を与えることができます。
ただし、与えるアクセス許可は最小限にしてください。 クライアントのコード(特にJavaScript)が公開されているならば、誰でもそのアクセス許可を得られるためです。
以上、良いチャットボットの作成を!